home *** CD-ROM | disk | FTP | other *** search
-
- #include "SXextend.h"
- #include <memory.h>
- #include <string.h>
-
- /*
- C support for BitArray class - simplified version
- */
-
- #define SYS_MODULE NULL
- #define BIT_MODULE "scratch"
-
- typedef enum {
- OPequal,
- OPand,
- OPor,
- OPxor
- } binaryOpcode ;
-
-
- /* prototypes */
- void *getPointer(SXobject arg, SXint *objSize);
- SXobject binaryOp(SXobject self, SXobject arg2, binaryOpcode op);
- SXobject equalOp(SXobject self, SXobject arg2);
- SXobject andOp(SXobject self, SXobject arg2);
- SXobject orOp(SXobject self, SXobject arg2);
- SXobject xorOp(SXobject self, SXobject arg2);
- SXobject notOp(SXobject self);
- SXobject clearOp(SXobject self);
- SXobject setBitOp(SXobject self, SXobject which, SXobject val);
- SXobject getBitOp(SXobject self, SXobject which);
- SXobject entryPoint(SXobject ld, SXobject grp, SXobject uni);
-
-
- /* lock down the external memory object and return it's pointer */
- void *getPointer(SXobject arg, SXint *objSize)
- {
- *objSize = SXintFrom(SXextGetIV(BIT_MODULE, arg, "bitSize"));
- SXlockMem(arg);
- return SXdereference(arg);
- }
-
- /* compare two BitArrays */
- SXobject binaryOp(SXobject self, SXobject arg2, binaryOpcode op)
- {
- register unsigned char *objp, *otherp;
- SXint objSize, otherSize;
- SXint opResult;
- SXobject arg1, result;
-
- if (op == OPequal) {
- result = trueObject;
- arg1 = self;
- }
- else {
- /* copy of self is destination */
- result = SXextCall(SYS_MODULE, "copy", self, NULL);
- arg1 = result;
- }
- objp = getPointer(arg1, &objSize);
- otherp = getPointer(arg2, &otherSize);
-
- if (objSize != otherSize) {
- SXunlockMem(arg1);
- SXunlockMem(arg2);
- SXextCall(SYS_MODULE, "report", generalError, SXmakeString("BitArray objects must have same size"), NULL);
- return SXundefined;
- }
-
- objSize /= 8;
- while (objSize--) {
- switch (op) {
- case OPequal : if (*objp != *otherp) {
- result = falseObject;
- goto bailOut;
- }
- break;
-
- case OPand : *objp &= *otherp;
- break;
-
- case OPor : *objp |= *otherp;
- break;
-
- case OPxor : *objp ^= *otherp;
- break;
- }
-
- objp++;
- otherp++;
- }
-
- bailOut:
- SXunlockMem(arg1);
- SXunlockMem(arg2);
-
- return result;
- }
-
- /* compare two BitArrays */
- SXobject equalOp(SXobject self, SXobject arg2)
- {
- return binaryOp(self, arg2, OPequal);
- }
-
- /* and two BitArrays */
- SXobject andOp(SXobject self, SXobject arg2)
- {
- return binaryOp(self, arg2, OPand);
- }
-
- /* or two BitArrays */
- SXobject orOp(SXobject self, SXobject arg2)
- {
- return binaryOp(self, arg2, OPor);
- }
-
- /* xor two BitArrays */
- SXobject xorOp(SXobject self, SXobject arg2)
- {
- return binaryOp(self, arg2, OPxor);
- }
-
- /* logical not of a BitArrays */
- SXobject notOp(SXobject self)
- {
- unsigned char *objp;
- SXint objSize;
- SXobject result;
-
- /* copy of self is destination */
- result = SXextCall(SYS_MODULE, "copy", self, NULL);
-
- /* get pointer to destination */
- objp = getPointer(result, &objSize);
-
- objSize /= 8;
- while (objSize--) {
- *objp++ = ~ *objp;
- }
-
- SXunlockMem(result);
- return result;
- }
-
- /* zero out a BitArrays */
- SXobject clearOp(SXobject self)
- {
- unsigned char *objp;
- SXint objSize;
-
- /* get pointer to destination */
- objp = getPointer(self, &objSize);
-
- objSize /= 8;
- while (objSize--) {
- *objp++ = 0;
- }
-
- SXunlockMem(self);
- return self;
- }
-
-
- /* write nth bit, zero-based, bit 0 is leftmost */
- SXobject setBitOp(SXobject self, SXobject which, SXobject val)
- {
- unsigned char *objp;
- SXint objSize;
- SXint bit;
- SXint result;
-
- /* get pointer to self */
- objp = getPointer(self, &objSize);
- bit = SXintFrom(which);
- if (bit < 0 || bit >= objSize) {
- SXunlockMem(self);
- SXextCall(SYS_MODULE, "report", generalError, SXmakeString("BitArray index out of bounds"), NULL);
- return SXundefined;
- }
-
- if (val == SXintToObject(0) || val == falseObject)
- objp[bit / 8] &= ~ (1 << (7 - (bit % 8)));
- else
- objp[bit / 8] |= (1 << (7 - (bit % 8)));
-
- SXunlockMem(self);
- return self;
- }
-
- /* read nth bit, zero-based, bit 0 is leftmost */
- SXobject getBitOp(SXobject self, SXobject which)
- {
- unsigned char *objp;
- SXint objSize;
- SXint bit;
- SXint result;
-
- /* get pointer to self */
- objp = getPointer(self, &objSize);
- bit = SXintFrom(which);
- if (bit < 0 || bit >= objSize) {
- SXunlockMem(self);
- SXextCall(SYS_MODULE, "report", generalError, SXmakeString("BitArray index out of bounds"), NULL);
- return SXundefined;
- }
-
- if (objp[bit / 8] & (1 << (7 - (bit % 8))))
- result = 1;
- else
- result = 0;
-
- SXunlockMem(self);
- return SXintToObject(result);
- }
-
- /* function executed when this library is loaded */
- SXobject entryPoint(SXobject ld, SXobject grp, SXobject uni)
- {
- SXobject myClass;
-
- myClass = SXextGetGlobal(BIT_MODULE, "BitArray");
- if (myClass == SXempty) {
- SXextCall(SYS_MODULE, "report", generalError, SXmakeString("Class BitArray not found"), NULL);
- return falseObject;
- }
-
- /* specialize BitArray with new methods */
- SXextMakeGeneric(BIT_MODULE, "bitEqual", myClass, equalOp);
- SXextMakeGeneric(BIT_MODULE, "bitAnd", myClass, andOp);
- SXextMakeGeneric(BIT_MODULE, "bitOr", myClass, orOp);
- SXextMakeGeneric(BIT_MODULE, "bitXor", myClass, xorOp);
- SXextMakeGeneric(BIT_MODULE, "bitNot", myClass, notOp);
-
- SXextMakeGeneric(BIT_MODULE, "clear", myClass, clearOp);
- SXextMakeGeneric(BIT_MODULE, "getBit", myClass, getBitOp);
- SXextMakeGeneric(BIT_MODULE, "setBit", myClass, setBitOp);
-
- return trueObject;
- }
-